package org.jing.r18.game.venusblood.hollow;

import org.jing.core.lang.ExceptionHandler;
import org.jing.core.lang.data.Carrier;
import org.jing.core.logger.JingLogger;
import org.jing.core.util.DateUtil;
import org.jing.core.util.FileUtil;
import org.jing.core.util.GenericUtil;
import org.jing.r18.game.comm.bmp.BMPFile;
import org.jing.r18.game.comm.kirikiri.KiriKiriHelper;
import org.jing.r18.game.comm.kirikiri.KiriKiriKsdFile;
import org.jing.r18.game.venusblood.util.Helper;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.util.Date;
import java.util.Scanner;

/**
 * Description: <br>
 * 武将经验等级关系: 10 * ((level - 1) ^ 2)
 *
 * @author: bks <br>
 * @createDate: 2025-05-13 <br>
 */
public class OperateSave {
    private static final JingLogger LOGGER = JingLogger.getLogger(OperateSave.class);

    private static final String OUTPUT_DIR = "unpack";

    private OperateSave() {
        while (true) {
            LOGGER.info("1:解包存档/2:打包存档/3:清空缓存/0:退出");
            Scanner scanner = new Scanner(System.in);
            if (scanner.hasNextLine()) {
                int code = scanner.nextInt();
                switch (code) {
                    case 1: {
                        unPack();
                        continue;
                    }
                    case 2: {
                        pack();
                        continue;
                    }
                    case 3: {
                        clear();
                        continue;
                    }
                    case 0:
                    default: return;
                }
            }
        }

    }

    private void unPack() {
        while (true) {
            LOGGER.info("请输入读取存档编号:");
            Scanner scanner = new Scanner(System.in);
            if (!scanner.hasNextLine()) {
                continue;
            }
            int saveIndex = scanner.nextInt();
            File file = null;
            for (String dir : Helper.getProjectConfig().getMyDocumentPaths()) {
                file = new File(dir + "/dualtail/venusblood_hollow_cn/data" + saveIndex + ".bmp");
                if (file.exists()) {
                    break;
                }
            }
            ExceptionHandler.publishIfMatch(null == file, "存档不存在");
            File outputDir = new File(file.getAbsoluteFile().getParent() + File.separator + OUTPUT_DIR);
            FileUtil.mkdirs(outputDir);
            File outputBmp = new File(outputDir.getAbsolutePath() + File.separator + "save" + saveIndex + ".bmp");
            File outputTjs2 = new File(outputDir.getAbsolutePath() + File.separator + "save" + saveIndex + ".tjs2");
            File outputInfo = new File(outputDir.getAbsolutePath() + File.separator + "save" + saveIndex + ".info");
            ExceptionHandler.publishIfMatch(!FileUtil.deleteFile(outputBmp) || !FileUtil.deleteFile(outputTjs2), "清除历史解包文件失败");
            try (
                FileOutputStream fos4Bmp = new FileOutputStream(outputBmp);
                FileOutputStream fosTjs2 = new FileOutputStream(outputTjs2);
                FileOutputStream fosInfo = new FileOutputStream(outputInfo)
            ) {
                byte[] allBytes = Files.readAllBytes(file.toPath());
                LOGGER.info("解析bmp文件...");
                BMPFile bmpFile = BMPFile.readBuffer(allBytes);
                LOGGER.info("bmp文件解析完成");
                LOGGER.info("存储bmp文件...");
                fos4Bmp.write(bmpFile.getBmpData());
                fos4Bmp.flush();
                LOGGER.info("bmp文件存储完成");

                LOGGER.info("解析tjs2文件...");
                int bmpFileSize = bmpFile.getFileHeader().getFileSize();
                byte[] dataBytes = new byte[allBytes.length - bmpFileSize];
                System.arraycopy(allBytes, bmpFileSize, dataBytes, 0, dataBytes.length);
                KiriKiriKsdFile ksdFile = KiriKiriHelper.decodeKsdFile(dataBytes);
                LOGGER.info("tjs2文件解析完成");
                LOGGER.info("存储tjs2文件...");
                String content = ksdFile.getContent();
                fosTjs2.write(content.getBytes(StandardCharsets.UTF_8));
                LOGGER.info("tjs2文件存储完成");

                Carrier infoC = new Carrier();
                infoC.setNumber("model", ksdFile.getModel());
                String infoJson = infoC.asSimpleJson();
                LOGGER.info("info: [{}]", infoJson);
                LOGGER.info("存储info文件...");
                fosInfo.write(infoJson.getBytes(StandardCharsets.UTF_8));
                LOGGER.info("info文件存储完成");
                break;
            } catch (IOException e) {
                LOGGER.error(e);
            }
        }
    }

    private void pack() {
        while (true) {
            LOGGER.info("请输入读取存档编号:");
            Scanner scanner = new Scanner(System.in);
            if (!scanner.hasNextLine()) {
                continue;
            }
            int saveIndex = scanner.nextInt();
            File bmpFile = null;
            File tjs2File = null;
            File infoFile = null;
            File saveFile = null;
            for (String dir : Helper.getProjectConfig().getMyDocumentPaths()) {
                File outputDir = new File(dir + "/dualtail/venusblood_hollow_cn" + File.separator + OUTPUT_DIR);
                if (outputDir.exists()) {
                    bmpFile = new File(outputDir.getAbsolutePath() + File.separator + "save" + saveIndex + ".bmp");
                    tjs2File = new File(outputDir.getAbsolutePath() + File.separator + "save" + saveIndex + ".tjs2");
                    infoFile = new File(outputDir.getAbsolutePath() + File.separator + "save" + saveIndex + ".info");
                    saveFile = new File(dir + "/dualtail/venusblood_hollow_cn/data" + saveIndex + ".bmp");
                    break;
                }
            }
            ExceptionHandler.publishIfMatch(null == bmpFile || !bmpFile.exists(), "bmp文件不存在");
            ExceptionHandler.publishIfMatch(!tjs2File.exists(), "tjs2文件不存在");
            ExceptionHandler.publishIfMatch(!infoFile.exists(), "info文件不存在");
            ExceptionHandler.publishIfMatch(saveFile.exists() && !saveFile.renameTo(new File(saveFile.getAbsoluteFile() + ".bak." + DateUtil.getCurrentDateString("yyyyMMddHHmmss"))), "备份存档文件失败");
            try (
                FileOutputStream fos = new FileOutputStream(saveFile)
            ) {
                byte[] allBytes = Files.readAllBytes(infoFile.toPath());
                String infoJson = new String(allBytes, StandardCharsets.UTF_8);
                LOGGER.info("info: [{}]", infoJson);
                Carrier infoC = Carrier.parseJson(infoJson);
                byte model = infoC.getNumber("model").byteValue();

                byte[] bmpBuffer = Files.readAllBytes(bmpFile.toPath());
                LOGGER.info("解析缩略图...");
                BMPFile bmpDto = BMPFile.readBuffer(bmpBuffer);
                LOGGER.info(bmpDto);
                LOGGER.info("缩略图解析完成");

                LOGGER.info("解析ksd文件...");
                allBytes = Files.readAllBytes(tjs2File.toPath());
                KiriKiriKsdFile ksdFile = new KiriKiriKsdFile();
                ksdFile.setModel(model);
                ksdFile.setContent(new String(allBytes, StandardCharsets.UTF_8));
                byte[] ksdBuffer = KiriKiriHelper.encodeKsdFile(ksdFile);
                LOGGER.info("ksd文件解析完成");

                LOGGER.info("输出存档文件");
                fos.write(bmpBuffer);
                fos.write(ksdBuffer);
                fos.flush();
                ExceptionHandler.publishIfMatch(!saveFile.setLastModified(new Date().getTime()), "更新修改时间失败");
                LOGGER.info("存档文件输出完毕");

                break;
            } catch (IOException e) {
                LOGGER.error(e);
            }
        }
    }

    private void clear() {
        LOGGER.info("将会清除存档目录下所有解包文件以及备份文件, 是否继续?(Y/N)");
        Scanner scanner = new Scanner(System.in);
        if (scanner.hasNextLine()) {
            if ("Y".equalsIgnoreCase(scanner.nextLine())) {
                for (String dir : Helper.getProjectConfig().getMyDocumentPaths()) {
                    File rootDir = new File(dir + "/dualtail/venusblood_hollow_cn");
                    if (rootDir.exists()) {
                        File[] files = rootDir.listFiles();
                        GenericUtil.loop(files, f$ -> {
                            if (f$.isDirectory() && f$.getName().equals(OUTPUT_DIR)) {
                                FileUtil.deleteFile(f$);
                                LOGGER.info("清理解包文件夹成功");
                            }
                            else if (f$.getName().matches("^.+?\\.bmp\\.bak\\.\\d{14}$")) {
                                FileUtil.deleteFile(f$);
                                LOGGER.info("删除存档备份: [{}]", f$.getName());
                            }
                        });
                    }
                }
            }
        }
    }

    public static void main(String[] args) {
        new OperateSave();
    }
}
